package com.raycloud.sdk.shopee.request;

import com.raycloud.sdk.shopee.constant.ApiField;
import com.raycloud.sdk.shopee.constant.MustField;
import com.raycloud.sdk.shopee.exception.ApiRuleException;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by donar on 17/6/12.
 */
public  class BaseShopeeRequest {
    private  Integer parentId;
    private  Integer shopId;
    private  String secretKey;
    private  Long timestamp;

    public BaseShopeeRequest(Integer shopId, Integer patenerId, String secret) {
        this.parentId=patenerId;
        this.shopId=shopId;
        this.secretKey=secret;
    }

    /**
     * @return 指定或默认的时间戳
     */
    public Long getTimestamp(){
        return timestamp;
    }

    /**
     * 设置时间戳，如果不设置,发送请求时将使用当时的时间。
     *
     * @param timestamp 时间戳
     */
    public void setTimestamp(Long timestamp){
        this.timestamp=timestamp;
    }
    public Integer getPartnerId(){
        return parentId;
    }
    public Integer getShopId() {
        return shopId;
    }
    public String getSecretKey(){
        return secretKey;
    }
    public Map<String,Object> getRequestMap(Object obj) throws InvocationTargetException, IllegalAccessException, ApiRuleException {
        Map<String,Object> map = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        Method[] methods = obj.getClass().getMethods();
        Map<String,Method> methodMap = new HashMap<String, Method>();
        for (Method m: methods){
            methodMap.put(m.getName(),m);
        }
        if(fields!=null){
            for(Field filed : fields){
                ApiField apiField = filed.getAnnotation(ApiField.class);
                MustField mustField = filed.getAnnotation(MustField.class);
                if(apiField!=null) {
                    String getMethodName = "get"+filed.getName().substring(0,1).toUpperCase()+filed.getName().substring(1);
                    Method method = methodMap.get(getMethodName);
                    if(method.getReturnType().equals(List.class)){
                        List<Object> list = (List<Object>) method.invoke(obj);
                        if(list!=null){
                            List<Map<String,Object>> listObj = new ArrayList<Map<String, Object>>();
                            for (Object o :list){
                                Map<String,Object> mapobj = getRequestMap(o);
                                listObj.add(mapobj);
                            }
                            map.put(apiField.value(),listObj);
                        }else{
                            if(mustField!=null) throw new ApiRuleException("missing required value",obj.getClass().getName()+":"+filed.getName());
                        }
                    }else{
                        Object o = method.invoke(obj);
                        if(o==null&&mustField!=null) throw new ApiRuleException("missing required value",obj.getClass().getName()+":"+filed.getName());
                        map.put(apiField.value(),o);
                    }
                }
            }
        }
        return map;
    }
}
